package com.shanzmoo.admin.manager.store;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.admin.domain.dto.StoreReceivePutawayUpdateDTO;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.StoreStockIoType;
import com.shanzmoo.base.exception.StoreException;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.manager.store.StoreMemberStockManager;
import com.shanzmoo.core.manager.store.StoreStockManager;
import com.shanzmoo.db.store.entity.*;
import com.shanzmoo.db.store.entity.query.StoreReceivePutawayQuery;
import com.shanzmoo.db.store.entity.vo.StoreReceivePutawayVO;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.db.store.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;


/**
 * 仓库收货上架信息 管理器
 *
 * @author Gzhao 2021-03-11
 */
@Slf4j
@Component
public class StoreReceivePutawayManager {

    @Autowired
    private IStoreReceivePutawayService storeReceivePutawayService;
    @Autowired
    private IStoreReceiveBillService storeReceiveBillService;
    @Autowired
    private IStoreReceiveBillDetailService storeReceiveBillDetailService;
    @Autowired
    private StoreStockManager storeStockManager;
    @Autowired
    private StoreMemberStockManager storeMemberStockManager;
    @Autowired
    private IStorePurchaseBillService storePurchaseBillService;
    @Autowired
    private IStorePurchaseBillDetailService storePurchaseBillDetailService;

    /**
     * 分页查询
     */
    public PageRespBase<StoreReceivePutawayVO> queryPage(StoreReceivePutawayQuery query) {
        Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StoreReceivePutawayVO> reList = storeReceivePutawayService.queryPageList(query);

        PageRespBase<StoreReceivePutawayVO> result = PageRespBase.create(page, reList);
        PageHelper.clearPage();
        return result;
    }

    /**
     * 商品仓库上架
     *
     * @param
     * @param userId
     * @return
     * @author Gzhao 2021/3/11
     */
    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> putaway(StoreReceivePutawayUpdateDTO updateDto, Integer currentUserId) {
        /*
            1. 判断上架状态
            2. 修改上架状态
            3. 更新收货单明细，上架数量,
            4. 若实际上架数量小于，上架单商品数量，则剩余数量重新生成一张上架单， 若数据相同，判断收货单是否收货完成
            5. 更新库存明细数据
            6. 若关联单据是采购单，并且含有仓库客户信息，同时生成仓库客户库存数据
         */
        StoreReceivePutawayEntity putawayEntity = storeReceivePutawayService.getById(updateDto.getId());
        Assert.isTrue(putawayEntity != null && putawayEntity.getStatus() == 0, "上架单信息异常");

        // 修改上架状态
        putawayEntity.setStatus(1);
        putawayEntity.setStoreCode(updateDto.getStoreCode());
        putawayEntity.setPutawayUser(currentUserId);
        putawayEntity.setPutawayTime(LocalDateTime.now());
        storeReceivePutawayService.updateById(putawayEntity);

        // 更新收货单明细，上架数量
        StoreReceiveBillEntity receiveBillEntity = storeReceiveBillService.getById(putawayEntity.getReceiveBillId());
        Assert.isTrue(receiveBillEntity != null && receiveBillEntity.getStatus() == 1,
                "收货单【" + receiveBillEntity.getBillNo() + "】信息异常");

        StoreReceiveBillDetailEntity receiveBillDetailEntity = storeReceiveBillDetailService.lambdaQuery()
                .eq(StoreReceiveBillDetailEntity::getDeleted, false)
                .eq(StoreReceiveBillDetailEntity::getBillId, receiveBillEntity.getId())
                .eq(StoreReceiveBillDetailEntity::getSku, putawayEntity.getSku())
                .one();
        Assert.isTrue(receiveBillDetailEntity != null, "收货明细异常");

        int totalPutawayNum = updateDto.getPutawayNum() + (receiveBillDetailEntity.getPutawayNum() == null ? 0 :
                receiveBillDetailEntity.getPutawayNum());
        Assert.isTrue(totalPutawayNum <= receiveBillDetailEntity.getSkuNum(), "数据异常");
        receiveBillDetailEntity.setPutawayNum(totalPutawayNum);
        storeReceiveBillDetailService.updateById(receiveBillDetailEntity);

        // 若实际上架数量小于，上架单商品数量，则剩余数量重新生成一张上架单，
        if (totalPutawayNum < receiveBillDetailEntity.getSkuNum()){
            StoreReceivePutawayEntity newPutawayEntity = new StoreReceivePutawayEntity();
            newPutawayEntity.setStatus(0);
            newPutawayEntity.setSku(putawayEntity.getSku());
            newPutawayEntity.setSkuNum(receiveBillDetailEntity.getSkuNum() - totalPutawayNum);
            newPutawayEntity.setReceiveBillId(putawayEntity.getReceiveBillId());
            storeReceivePutawayService.save(newPutawayEntity);
        } else {
            // 若数据相同，判断收货单是否收货完成
            List<StoreReceiveBillDetailEntity> receiveBillDetailList = storeReceiveBillDetailService.lambdaQuery()
                    .eq(StoreReceiveBillDetailEntity::getDeleted, false)
                    .eq(StoreReceiveBillDetailEntity::getBillId, receiveBillEntity)
                    .list();
            boolean receiveOver = true;
            for (StoreReceiveBillDetailEntity rd : receiveBillDetailList) {
                if (!rd.getSkuNum().equals(rd.getPutawayNum())) {
                    receiveOver = false;
                    break;
                }
            }
            if (receiveOver) {
                receiveBillEntity.setStatus(2);
                storeReceiveBillService.updateById(receiveBillEntity);
            }
        }

        // 更新库存明细数据
        StoreStockIoEntity ioEntity = new StoreStockIoEntity();
        ioEntity.setSku(putawayEntity.getSku());
        if (receiveBillEntity.getOriginOrderType() == 1) {
            ioEntity.setType(StoreStockIoType.PURCHASE_IN);
        } else {
            throw new StoreException("上架失败，当前收货单关联单据类型异常");
        }
        ioEntity.setStoreCode(updateDto.getStoreCode());
        ioEntity.setFlow(true);
        ioEntity.setSkuNum(updateDto.getPutawayNum());
        ioEntity.setOriginBillType(2);
        ioEntity.setOriginBill(receiveBillEntity.getOriginOrder());
        ioEntity.setCreateUser(CurrentUserCache.getUserId());
        storeStockManager.updateByIo(ioEntity, currentUserId);

        // 若关联单据是采购单
        if (receiveBillEntity.getOriginOrderType() == 1) {

            StorePurchaseBillEntity purchaseBill = storePurchaseBillService.lambdaQuery()
                    .eq(StorePurchaseBillEntity::getDeleted, false)
                    .eq(StorePurchaseBillEntity::getBillNo, receiveBillEntity.getOriginOrder())
                    .one();
            Assert.isTrue(purchaseBill != null, "上架失败，未获取到采购订单");

            // 更新采购订单的到货数量
            StorePurchaseBillDetailEntity purchaseBillDetail = storePurchaseBillDetailService.lambdaQuery()
                    .eq(StorePurchaseBillDetailEntity::getDeleted, false)
                    .eq(StorePurchaseBillDetailEntity::getBillId, purchaseBill.getId())
                    .eq(StorePurchaseBillDetailEntity::getSku, putawayEntity.getSku())
                    .one();
            BigDecimal receiveNum = NumberUtil.add(purchaseBillDetail.getReceiveNum(), updateDto.getPutawayNum());
            purchaseBillDetail.setReceiveNum(receiveNum.intValue());
            storePurchaseBillDetailService.updateById(purchaseBillDetail);

            // 若含有仓库客户信息，同时生成仓库客户库存数据
            if (purchaseBill.getMemberId() != null && purchaseBill.getMemberId() > 0) {
                StoreMemberStockIoEntity memberStockIoEntity = new StoreMemberStockIoEntity();
                BeanUtil.copyProperties(ioEntity, memberStockIoEntity);
                memberStockIoEntity.setMemberId(purchaseBill.getMemberId());
                storeMemberStockManager.updateByIo(memberStockIoEntity, currentUserId);
            }

        }
        return SResponse.ok(Boolean.TRUE);
    }
}
